package com.zh.service.impl;

import com.zh.domain.Model.ws.*;
import com.zh.domain.dto.iteration.UpdateIterationRequest;
import com.zh.domain.dto.milestone.UpdateMileStoneRequest;
import com.zh.domain.dto.requirement.UpdateRequirementRequest;
import com.zh.domain.dto.task.UpdateTaskRequest;
import com.zh.service.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;

@Service
@Slf4j
public class WebsocketServiceImpl implements WebsocketService {
    @Resource
    private MilestoneService milestoneService;
    @Resource
    private IterationService iterationService;
    @Resource
    private RequirementsService requirementsService;
    @Resource
    private TaskService taskService;

    private static final String UPDATE = "update";

    private static final String INIT= "init";

    @Override
    @Transactional
    public Boolean handleTableMessage(TableMessageModel tableMessageModel) {
        String operation = tableMessageModel.getOperation();
        if (UPDATE.equals(operation)) {
            return doUpdate(tableMessageModel, tableMessageModel.getType());
        }
        else if(INIT.equals(operation)){
            return true;
        }
        return false;
    }

    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public Boolean doUpdate(TableMessageModel tableMessageModel, Integer type) {
        Integer sendId = tableMessageModel.getSendId();
        //type 0:里程碑 1:迭代 2:需求 3:任务
        switch (type) {
            case 0: {
                UpdateMileStoneRequest updateMileStoneRequest = tableMessageModel.getUpdateMileStoneRequest();
                return milestoneService.updateMileStone(sendId, updateMileStoneRequest);
            }
            case 1: {
                UpdateIterationRequest updateIterationRequest = tableMessageModel.getUpdateIterationRequest();
                return iterationService.updateIteration(sendId, updateIterationRequest);
            }

            case 2: {
                UpdateRequirementRequest updateRequirementRequest = tableMessageModel.getUpdateRequirementRequest();
                return requirementsService.updateRequirement(sendId, updateRequirementRequest);
            }
            case 3: {
                UpdateTaskRequest updateTaskRequest = tableMessageModel.getUpdateTaskRequest();
                return taskService.updateTask(sendId, updateTaskRequest);
            }
        }
        return false;

    }

    /**
     * 处理编辑消息
     *
     * @param editInfoModel 编辑信息模型
     * @return 若status是editing, 返回值代表是否成功获取到编辑权;
     * 若status是complete,返回值代表是否成功释放编辑权
     */
    @Override
    public boolean handleEditMessage(EditInfoModel editInfoModel) {
        // 参数校验
        if (editInfoModel == null || editInfoModel.getCellId() == null || editInfoModel.getStatus() == null) {
            log.error("编辑消息参数无效: {}", editInfoModel);
            return false;
        }

        String cellId = editInfoModel.getCellId();
        String status = editInfoModel.getStatus();

        // 根据状态分别处理
        switch (status) {
            case EDIT_STATUS_EDITING:
                return handleEditEditing(cellId, editInfoModel.getEditorInfo());
            case EDIT_STATUS_RELEASE:
                return handleEditRelease(cellId, editInfoModel.getEditorInfo());
            default:
                log.error("未知的编辑状态: {}", status);
                return false;
        }
    }

    /**
     * 处理获取编辑权请求
     *
     * @param cellId 单元格ID
     * @param editor 请求编辑的用户信息
     * @return 是否成功获取编辑权
     */
    private boolean handleEditEditing(String cellId, SimpleUserModel editor) {
        // 检查是否已有人在编辑
        SimpleUserModel currentEditor = editStatusMap.get(cellId);
        if (currentEditor != null) {
            // 如果是同一个用户重复请求,视为成功
            if (currentEditor.getId().equals(editor.getId())) {
                log.info("用户 {} 重复请求编辑单元格 {}", editor.getName(), cellId);
                return true;
            }
            // 其他用户正在编辑,拒绝请求
            log.warn("获取编辑权失败: 单元格 {} 正在被用户 {} 编辑", cellId, currentEditor.getName());
            return false;
        }

        // 没有人在编辑,授予编辑权
        editStatusMap.put(cellId, editor);
        log.info("用户 {} 获得单元格 {} 的编辑权", editor.getName(), cellId);
        log.info("当前表格编辑权映射map:{}", editStatusMap);
        return true;
    }

    /**
     * 处理释放编辑权请求
     *
     * @param cellId 单元格ID
     * @param editor 请求释放编辑权的用户信息
     * @return 是否成功释放编辑权
     */
    private boolean handleEditRelease(String cellId, SimpleUserModel editor) {
        SimpleUserModel currentEditor = editStatusMap.get(cellId);

        // 检查单元格是否存在编辑状态
        if (currentEditor == null) {
            log.warn("释放编辑权: 单元格 {} 不存在编辑状态", cellId);
            return true;
        }

        // 检查是否是持有编辑权的用户
        if (!currentEditor.getId().equals(editor.getId())) {
            log.error("释放编辑权失败: 用户 {} 试图释放用户 {} 持有的编辑权",
                    editor.getName(), currentEditor.getName());
            return false;
        }

        // 释放编辑权
        editStatusMap.remove(cellId);
        log.info("用户 {} 释放了单元格 {} 的编辑权", editor.getName(), cellId);
        log.info("当前表格编辑权映射map:{}", editStatusMap);
        return true;
    }

    /**
     * 获取单元格当前的编辑者
     *
     * @param cellId 单元格ID
     * @return 当前编辑者信息, 如果没有则返回null
     */
    public SimpleUserModel getEditingUser(String cellId) {
        return editStatusMap.get(cellId);
    }

    /**
     * 清理用户的所有编辑状态
     * 用于用户断开连接时清理其占用的编辑权
     *
     * @param userId 需要清理的用户ID
     */
    public List<EditReturnModel> clearUserEditStatus(Integer userId) {
        List<EditReturnModel> releasedEdits = new ArrayList<>();

        editStatusMap.entrySet().removeIf(entry -> {
            if (entry.getValue().getId().equals(userId)) {
                EditReturnModel editReturnModel = new EditReturnModel();
                EditInfoModel editInfoModel = new EditInfoModel();
                editInfoModel.setCellId(entry.getKey());
                editInfoModel.setStatus(EDIT_STATUS_RELEASE);
                editReturnModel.setEditInfo(editInfoModel);
                editReturnModel.setResult(EDIT_STATUS_RELEASE);
                releasedEdits.add(editReturnModel);
                return true;
            }
            return false;
        });
        log.info("已清理用户 {} 的所有编辑状态", userId);
        return releasedEdits;
    }

    public Map<String, SimpleUserModel> getCurrentEditStatus(){
        // 返回一个只读的视图
        return Collections.unmodifiableMap(editStatusMap);
    }

}
